home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #11 / Amiga Plus CD - 2002 - No. 11.iso / Tools / Development / libogg / libvorbis-1.0rc3 / vq / build.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-10-27  |  4.2 KB  |  196 lines

  1. /********************************************************************
  2.  *                                                                  *
  3.  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
  4.  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  5.  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
  6.  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  7.  *                                                                  *
  8.  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
  9.  * by the XIPHOPHORUS Company http://www.xiph.org/                  *
  10.  *                                                                  *
  11.  ********************************************************************
  12.  
  13.  function: utility main for building codebooks from training sets
  14.  last mod: $Id: build.c,v 1.21 2001/12/20 01:00:39 segher Exp $
  15.  
  16.  ********************************************************************/
  17.  
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20. #include <math.h>
  21. #include <string.h>
  22. #include <errno.h>
  23. #include "bookutil.h"
  24.  
  25. #include "vqgen.h"
  26. #include "vqsplit.h"
  27.  
  28. static char *linebuffer=NULL;
  29. static int  lbufsize=0;
  30. static char *rline(FILE *in,FILE *out){
  31.   long sofar=0;
  32.   if(feof(in))return NULL;
  33.  
  34.   while(1){
  35.     int gotline=0;
  36.  
  37.     while(!gotline){
  38.       if(sofar>=lbufsize){
  39.     if(!lbufsize){    
  40.       lbufsize=1024;
  41.       linebuffer=_ogg_malloc(lbufsize);
  42.     }else{
  43.       lbufsize*=2;
  44.       linebuffer=_ogg_realloc(linebuffer,lbufsize);
  45.     }
  46.       }
  47.       {
  48.     long c=fgetc(in);
  49.     switch(c){
  50.     case '\n':
  51.     case EOF:
  52.       gotline=1;
  53.       break;
  54.     default:
  55.       linebuffer[sofar++]=c;
  56.       linebuffer[sofar]='\0';
  57.       break;
  58.     }
  59.       }
  60.     }
  61.     
  62.     if(linebuffer[0]=='#'){
  63.       sofar=0;
  64.     }else{
  65.       return(linebuffer);
  66.     }
  67.   }
  68. }
  69.  
  70. /* command line:
  71.    buildvq file
  72. */
  73.  
  74. int main(int argc,char *argv[]){
  75.   vqgen v;
  76.   static_codebook c;
  77.   codebook b;
  78.   quant_meta q;
  79.  
  80.   long *quantlist=NULL;
  81.   int entries=-1,dim=-1,aux=-1;
  82.   FILE *out=NULL;
  83.   FILE *in=NULL;
  84.   char *line,*name;
  85.   long i,j,k;
  86.  
  87.   b.c=&c;
  88.  
  89.   if(argv[1]==NULL){
  90.     fprintf(stderr,"Need a trained data set on the command line.\n");
  91.     exit(1);
  92.   }
  93.  
  94.   {
  95.     char *ptr;
  96.     char *filename=strdup(argv[1]);
  97.  
  98.     in=fopen(filename,"r");
  99.     if(!in){
  100.       fprintf(stderr,"Could not open input file %s\n",filename);
  101.       exit(1);
  102.     }
  103.     
  104.     ptr=strrchr(filename,'-');
  105.     if(ptr){
  106.       *ptr='\0';
  107.       name=strdup(filename);
  108.       sprintf(ptr,".vqh");
  109.     }else{
  110.       name=strdup(filename);
  111.       strcat(filename,".vqh");
  112.     }
  113.  
  114.     out=fopen(filename,"w");
  115.     if(out==NULL){
  116.       fprintf(stderr,"Unable to open %s for writing\n",filename);
  117.       exit(1);
  118.     }
  119.   }
  120.  
  121.   /* suck in the trained book */
  122.  
  123.   /* read book type, but it doesn't matter */
  124.   line=rline(in,out);
  125.   
  126.   line=rline(in,out);
  127.   if(sscanf(line,"%d %d %d",&entries,&dim,&aux)!=3){
  128.     fprintf(stderr,"Syntax error reading book file\n");
  129.     exit(1);
  130.   }
  131.   
  132.   /* just use it to allocate mem */
  133.   vqgen_init(&v,dim,0,entries,0.f,NULL,NULL,0);
  134.   
  135.   /* quant */
  136.   line=rline(in,out);
  137.   if(sscanf(line,"%ld %ld %d %d",&q.min,&q.delta,
  138.         &q.quant,&q.sequencep)!=4){
  139.     fprintf(stderr,"Syntax error reading book file\n");
  140.     exit(1);
  141.   }
  142.   
  143.   /* quantized entries */
  144.   /* save quant data; we don't want to requantize later as our method
  145.      is currently imperfect wrt repeated application */
  146.   i=0;
  147.   quantlist=_ogg_malloc(sizeof(long)*v.elements*v.entries);
  148.   for(j=0;j<entries;j++){
  149.     float a;
  150.     for(k=0;k<dim;k++){
  151.       line=rline(in,out);
  152.       sscanf(line,"%f",&a);
  153.       v.entrylist[i]=a;
  154.       quantlist[i++]=rint(a);
  155.     }
  156.   }    
  157.   
  158.   /* ignore bias */
  159.   for(j=0;j<entries;j++)line=rline(in,out);
  160.   free(v.bias);
  161.   v.bias=NULL;
  162.   
  163.   /* training points */
  164.   {
  165.     float *b=alloca(sizeof(float)*(dim+aux));
  166.     i=0;
  167.     v.entries=0; /* hack to avoid reseeding */
  168.     while(1){
  169.       for(k=0;k<dim+aux;k++){
  170.     line=rline(in,out);
  171.     if(!line)break;
  172.     sscanf(line,"%f",b+k);
  173.       }
  174.       if(feof(in))break;
  175.       vqgen_addpoint(&v,b,NULL);
  176.     }
  177.     v.entries=entries;
  178.   }
  179.   
  180.   fclose(in);
  181.   vqgen_unquantize(&v,&q);
  182.  
  183.   /* build the book */
  184.   vqsp_book(&v,&b,quantlist);
  185.   c.q_min=q.min;
  186.   c.q_delta=q.delta;
  187.   c.q_quant=q.quant;
  188.   c.q_sequencep=q.sequencep;
  189.  
  190.   /* save the book in C header form */
  191.   write_codebook(out,name,b.c);
  192.  
  193.   fclose(out);
  194.   exit(0);
  195. }
  196.